package com.aliothservice.catfish;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.aliothservice.catfish.admin.AdminController;
import com.aliothservice.catfish.admin.request.AddIdentityTemplateRequest;
import com.aliothservice.catfish.admin.request.AddNoteToVehicleBindingRequestRequest;
import com.aliothservice.catfish.admin.request.AddNoteToWarehouseBindingRequestRequest;
import com.aliothservice.catfish.admin.request.AddServiceTemplateRequest;
import com.aliothservice.catfish.admin.request.AdminGetVerificationCodeRequest;
import com.aliothservice.catfish.admin.request.AdminSignInRequest;
import com.aliothservice.catfish.admin.request.AdminUpdatePasswordRequest;
import com.aliothservice.catfish.admin.request.ApproveEnterprisePendingRequest;
import com.aliothservice.catfish.admin.request.ApproveIndividualPendingRequest;
import com.aliothservice.catfish.admin.request.ApproveProductPendingRequest;
import com.aliothservice.catfish.admin.request.ApproveVehiclePendingRequest;
import com.aliothservice.catfish.admin.request.ApproveWarehousePendingRequest;
import com.aliothservice.catfish.admin.request.ApproveWithdrawRequestRequest;
import com.aliothservice.catfish.admin.request.BindVehicleRequest;
import com.aliothservice.catfish.admin.request.BindWarehouseRequest;
import com.aliothservice.catfish.admin.request.DeleteIdentityTemplateRequest;
import com.aliothservice.catfish.admin.request.DeleteServiceTemplateRequest;
import com.aliothservice.catfish.admin.request.EnterprisePendingListRequest;
import com.aliothservice.catfish.admin.request.FilterIndividualUsersRequest;
import com.aliothservice.catfish.admin.request.HeartbeatMockupRequest;
import com.aliothservice.catfish.admin.request.HumidityMockupRequest;
import com.aliothservice.catfish.admin.request.IdentityTemplateListRequest;
import com.aliothservice.catfish.admin.request.IndividualPendingListRequest;
import com.aliothservice.catfish.admin.request.InfoUpdateForAdminConsoleRequest;
import com.aliothservice.catfish.admin.request.ListAppealRequestsRequest;
import com.aliothservice.catfish.admin.request.ListEnterpriseUsersRequest;
import com.aliothservice.catfish.admin.request.ListIndividualUsersRequest;
import com.aliothservice.catfish.admin.request.ListUsersRequest;
import com.aliothservice.catfish.admin.request.LocationMockupRequest;
import com.aliothservice.catfish.admin.request.MockupResultRequest;
import com.aliothservice.catfish.admin.request.ProcessedVehicleBindingRequestRequest;
import com.aliothservice.catfish.admin.request.ProcessedWarehouseBindingRequestRequest;
import com.aliothservice.catfish.admin.request.ProductPendingListRequest;
import com.aliothservice.catfish.admin.request.QueryIndividualUsersRequest;
import com.aliothservice.catfish.admin.request.QueryOnlineVehiclesRequest;
import com.aliothservice.catfish.admin.request.QueryOnlineWarehouseRequest;
import com.aliothservice.catfish.admin.request.QueryProductRequest;
import com.aliothservice.catfish.admin.request.QueryUserRequest;
import com.aliothservice.catfish.admin.request.QueryVehicleOrdersRequest;
import com.aliothservice.catfish.admin.request.QueryVehicleRequest;
import com.aliothservice.catfish.admin.request.QueryWarehouseRequest;
import com.aliothservice.catfish.admin.request.RejectEnterprisePendingRequest;
import com.aliothservice.catfish.admin.request.RejectIndividualPendingRequest;
import com.aliothservice.catfish.admin.request.RejectProductPendingRequest;
import com.aliothservice.catfish.admin.request.RejectVehiclePendingRequest;
import com.aliothservice.catfish.admin.request.RejectWarehousePendingRequest;
import com.aliothservice.catfish.admin.request.RejectWithdrawRequestRequest;
import com.aliothservice.catfish.admin.request.ResolveAppealRequest;
import com.aliothservice.catfish.admin.request.ResolvedAppealListRequest;
import com.aliothservice.catfish.admin.request.ServiceTemplateListRequest;
import com.aliothservice.catfish.admin.request.TemperatureMockupRequest;
import com.aliothservice.catfish.admin.request.VehicleBindingRequestListRequest;
import com.aliothservice.catfish.admin.request.VehiclePendingListRequest;
import com.aliothservice.catfish.admin.request.WarehouseBindingRequestListRequest;
import com.aliothservice.catfish.admin.request.WarehousePendingListRequest;
import com.aliothservice.catfish.admin.request.WithdrawRequestListRequest;
import com.aliothservice.catfish.cart.CartController;
import com.aliothservice.catfish.cart.request.AddProductIntoCartRequest;
import com.aliothservice.catfish.cart.request.AddVehicleIntoCartRequest;
import com.aliothservice.catfish.cart.request.AddWarehouseIntoCartRequest;
import com.aliothservice.catfish.cart.request.DeleteServicesFromCartRequest;
import com.aliothservice.catfish.cart.request.MyCartCountingRequest;
import com.aliothservice.catfish.cart.request.MyCartRequest;
import com.aliothservice.catfish.data.AndroidVersion;
import com.aliothservice.catfish.device.DeviceController;
import com.aliothservice.catfish.device.request.VehicleBindingRequestRequest;
import com.aliothservice.catfish.device.request.VehicleHumidityDocumentRequest;
import com.aliothservice.catfish.device.request.VehicleLocationDocumentRequest;
import com.aliothservice.catfish.device.request.VehicleTemperatureDocumentRequest;
import com.aliothservice.catfish.device.request.WarehouseBindingRequestRequest;
import com.aliothservice.catfish.identity.IdentityController;
import com.aliothservice.catfish.identity.request.AccountBalanceRequest;
import com.aliothservice.catfish.identity.request.CompleteEnterpriseInfoRequest;
import com.aliothservice.catfish.identity.request.CompleteIndividualInfoRequest;
import com.aliothservice.catfish.identity.request.CropAvatarRequest;
import com.aliothservice.catfish.identity.request.GetCertificateRequest;
import com.aliothservice.catfish.identity.request.GetVerificationCodeRequest;
import com.aliothservice.catfish.identity.request.PendingEnterpriseInfoRequest;
import com.aliothservice.catfish.identity.request.PendingIndividualInfoRequest;
import com.aliothservice.catfish.identity.request.ResetPasswordRequest;
import com.aliothservice.catfish.identity.request.SetUserDataRequest;
import com.aliothservice.catfish.identity.request.SignInRequest;
import com.aliothservice.catfish.identity.request.SignOutRequest;
import com.aliothservice.catfish.identity.request.SignUpRequest;
import com.aliothservice.catfish.identity.request.UpdateEnterpriseCertInfoRequest;
import com.aliothservice.catfish.identity.request.UpdateEnterpriseInfoRequest;
import com.aliothservice.catfish.identity.request.UpdateIndividualCertInfoRequest;
import com.aliothservice.catfish.identity.request.UpdateIndividualInfoRequest;
import com.aliothservice.catfish.identity.request.UpdatePasswordRequest;
import com.aliothservice.catfish.identity.request.UserDataRequest;
import com.aliothservice.catfish.identity.request.UserInfoRequest;
import com.aliothservice.catfish.identity.request.ValidateVerificationCodeRequest;
import com.aliothservice.catfish.identity.request.WithdrawRequestRequest;
import com.aliothservice.catfish.maintenance.MaintenanceController;
import com.aliothservice.catfish.message.MessageController;
import com.aliothservice.catfish.message.request.DeleteMessagesRequest;
import com.aliothservice.catfish.message.request.ListMessagesRequest;
import com.aliothservice.catfish.message.request.ReadMessagesRequest;
import com.aliothservice.catfish.message.request.UnreadMessageCountRequest;
import com.aliothservice.catfish.order.OrderController;
import com.aliothservice.catfish.order.request.BuyerReceivedProductOrderRequest;
import com.aliothservice.catfish.order.request.CompletedProductOrdersRequest;
import com.aliothservice.catfish.order.request.CompletedVehicleOrdersRequest;
import com.aliothservice.catfish.order.request.CompletedWarehouseOrdersRequest;
import com.aliothservice.catfish.order.request.CreateOrderRequest;
import com.aliothservice.catfish.order.request.DeleteOrderRequest;
import com.aliothservice.catfish.order.request.LoadPendingWarehouseOrdersRequest;
import com.aliothservice.catfish.order.request.LoadedWarehouseOrdersRequest;
import com.aliothservice.catfish.order.request.OrderInfoRequest;
import com.aliothservice.catfish.order.request.OrderPaymentRequestRequest;
import com.aliothservice.catfish.order.request.OverallProductOrderCountingRequest;
import com.aliothservice.catfish.order.request.OverallVehicleOrderCountingRequest;
import com.aliothservice.catfish.order.request.OverallWarehouseOrderCountingRequest;
import com.aliothservice.catfish.order.request.ReviewPendingProductOrdersRequest;
import com.aliothservice.catfish.order.request.ReviewPendingVehicleOrdersRequest;
import com.aliothservice.catfish.order.request.ReviewPendingWarehouseOrdersRequest;
import com.aliothservice.catfish.order.request.SellerAssignVehicleToVehicleOrderRequest;
import com.aliothservice.catfish.order.request.SellerLoadedWarehouseOrderRequest;
import com.aliothservice.catfish.order.request.SellerOffloadWarehouseOrderRequest;
import com.aliothservice.catfish.order.request.SellerReviewListingRequest;
import com.aliothservice.catfish.order.request.SellerShippedProductOrderRequest;
import com.aliothservice.catfish.order.request.SellerTransportedVehicleOrderRequest;
import com.aliothservice.catfish.order.request.SellerTransportsVehicleOrderRequest;
import com.aliothservice.catfish.order.request.ShipPendingProductOrdersRequest;
import com.aliothservice.catfish.order.request.ShippedProductOrdersRequest;
import com.aliothservice.catfish.order.request.SubmitAppealRequestRequest;
import com.aliothservice.catfish.order.request.TransactionListingRequest;
import com.aliothservice.catfish.order.request.TransportOnGoingVehicleOrdersRequest;
import com.aliothservice.catfish.order.request.TransportPendingVehicleOrdersRequest;
import com.aliothservice.catfish.order.request.UnpaidProductOrdersRequest;
import com.aliothservice.catfish.order.request.UnpaidVehicleOrdersRequest;
import com.aliothservice.catfish.order.request.UnpaidWarehouseOrdersRequest;
import com.aliothservice.catfish.order.request.WriteProductOrderReviewRequest;
import com.aliothservice.catfish.order.request.WriteVehicleOrderReviewRequest;
import com.aliothservice.catfish.order.request.WriteWarehouseOrderReviewRequest;
import com.aliothservice.catfish.product.ProductController;
import com.aliothservice.catfish.product.request.AddDriverRequest;
import com.aliothservice.catfish.product.request.AddProductPendingRequest;
import com.aliothservice.catfish.product.request.AddVehiclePendingRequest;
import com.aliothservice.catfish.product.request.AddWarehousePendingRequest;
import com.aliothservice.catfish.product.request.ApprovedProductListRequest;
import com.aliothservice.catfish.product.request.ApprovedVehicleListRequest;
import com.aliothservice.catfish.product.request.ApprovedWarehouseListRequest;
import com.aliothservice.catfish.product.request.CancelCompleteVehicleServiceRequest;
import com.aliothservice.catfish.product.request.CancelProductServiceRequest;
import com.aliothservice.catfish.product.request.CancelWarehouseServiceRequest;
import com.aliothservice.catfish.product.request.CompleteProductPendingRequest;
import com.aliothservice.catfish.product.request.CompleteVehiclePendingRequest;
import com.aliothservice.catfish.product.request.CompleteVehicleServiceCountingRequest;
import com.aliothservice.catfish.product.request.CompleteWarehousePendingRequest;
import com.aliothservice.catfish.product.request.CropProductPendingResourceRequest;
import com.aliothservice.catfish.product.request.CropVehiclePendingResourceRequest;
import com.aliothservice.catfish.product.request.CropWarehousePendingResourceRequest;
import com.aliothservice.catfish.product.request.DeleteApprovedProductRequest;
import com.aliothservice.catfish.product.request.DeleteApprovedVehicleRequest;
import com.aliothservice.catfish.product.request.DeleteApprovedWarehouseRequest;
import com.aliothservice.catfish.product.request.DeleteDriverRequest;
import com.aliothservice.catfish.product.request.DeleteRejectedProductRequest;
import com.aliothservice.catfish.product.request.DeleteRejectedVehicleRequest;
import com.aliothservice.catfish.product.request.DeleteRejectedWarehouseRequest;
import com.aliothservice.catfish.product.request.DriverListingRequest;
import com.aliothservice.catfish.product.request.DriverResourceRequest;
import com.aliothservice.catfish.product.request.InReviewProductPendingListRequest;
import com.aliothservice.catfish.product.request.InReviewVehiclePendingListRequest;
import com.aliothservice.catfish.product.request.InReviewWarehousePendingListRequest;
import com.aliothservice.catfish.product.request.ProductCountingRequest;
import com.aliothservice.catfish.product.request.ProductForProductServiceRequest;
import com.aliothservice.catfish.product.request.ProductInfoRequest;
import com.aliothservice.catfish.product.request.ProductResourceRequest;
import com.aliothservice.catfish.product.request.ProductServiceCountingRequest;
import com.aliothservice.catfish.product.request.ProductServiceListingRequest;
import com.aliothservice.catfish.product.request.ProductSpecListingRequest;
import com.aliothservice.catfish.product.request.PublishCompleteVehicleServiceRequest;
import com.aliothservice.catfish.product.request.PublishProductServiceRequest;
import com.aliothservice.catfish.product.request.PublishWarehouseServiceRequest;
import com.aliothservice.catfish.product.request.RejectedProductListRequest;
import com.aliothservice.catfish.product.request.RejectedVehicleListRequest;
import com.aliothservice.catfish.product.request.RejectedWarehouseListRequest;
import com.aliothservice.catfish.product.request.SearchCompleteVehicleServiceRequest;
import com.aliothservice.catfish.product.request.SearchProductServiceRequest;
import com.aliothservice.catfish.product.request.SearchWarehouseServiceRequest;
import com.aliothservice.catfish.product.request.UpdateDriverRequest;
import com.aliothservice.catfish.product.request.UpdateProductInfoRequest;
import com.aliothservice.catfish.product.request.UpdateVehicleInfoRequest;
import com.aliothservice.catfish.product.request.UpdateWarehouseInfoRequest;
import com.aliothservice.catfish.product.request.VehicleCountingRequest;
import com.aliothservice.catfish.product.request.VehicleInfoRequest;
import com.aliothservice.catfish.product.request.VehicleResourceRequest;
import com.aliothservice.catfish.product.request.VehicleServiceListingRequest;
import com.aliothservice.catfish.product.request.VehicleSpecListingRequest;
import com.aliothservice.catfish.product.request.VehicleSpecStockRequest;
import com.aliothservice.catfish.product.request.VehiclesForCompleteVehicleServiceRequest;
import com.aliothservice.catfish.product.request.WarehouseCountingRequest;
import com.aliothservice.catfish.product.request.WarehouseForWarehouseServiceRequest;
import com.aliothservice.catfish.product.request.WarehouseInfoRequest;
import com.aliothservice.catfish.product.request.WarehouseResourceRequest;
import com.aliothservice.catfish.product.request.WarehouseServiceCountingRequest;
import com.aliothservice.catfish.product.request.WarehouseServiceListingRequest;
import com.aliothservice.catfish.product.request.WarehouseSpecListingRequest;
import com.aliothservice.catfish.validation.RequestValidator;
import com.alipay.util.AlipayNotify;

@RestController
public class FacadeController {
	
	// identity
	
	@CrossOrigin
	@RequestMapping(value="getVerificationCode", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> getVerificationCode(@RequestBody @Validated GetVerificationCodeRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("getVerificationCode - " + req.getPhoneNumber());
		}
		
		return identityController.getVerificationCode(req);
	}
	
	@RequestMapping(value="validateVerificationCode", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> validateVerificationCode(@RequestBody ValidateVerificationCodeRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("validateVerificationCode - " + req.getPhoneNumber());
		}
		
		return identityController.validateVerificationCode(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="signUp", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> signUp(@RequestBody @Validated SignUpRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("signUp - " + req.getPhoneNumber());
		}
		
		return identityController.signUp(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="signIn", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> signIn(@RequestBody @Validated SignInRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("signIn - " + req.getPhoneNumber());
		}
		
		return identityController.signIn(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="signOut", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> signOut(@RequestBody @Validated SignOutRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("signOut - " + req.getToken());
		}
		
		return identityController.signOut(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="resetPassword", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> resetPassword(@RequestBody @Validated ResetPasswordRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("resetPassword - " + req.getPhoneNumber());
		}
		
		return identityController.resetPassword(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="updatePassword", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> updatePassword(@RequestBody @Validated UpdatePasswordRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("updatePassword - token:" + req.getToken());
		}
		
		return identityController.updatePassword(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="userInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, Object> userInfo(@RequestBody @Validated UserInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("userInfo - token:" + req.getToken());
		}
		
		return identityController.userInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="setUserData", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> setUserData(@RequestBody @Validated SetUserDataRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("setUserData - token:" + req.getToken());
		}
		
		return identityController.setUserData(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="userData", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> userData(@RequestBody @Validated UserDataRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("userData - token:" + req.getToken());
		}
		
		return identityController.userData(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="withdrawRequest", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> withdrawRequest(@RequestBody @Validated WithdrawRequestRequest req) throws UnsupportedEncodingException {
		if (logger.isDebugEnabled()) {
			logger.debug("withdrawRequest - token:" + req.getToken());
		}
		
		return identityController.withdrawRequest(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="updateIndividualInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> updateIndividualInfo(@RequestBody @Validated UpdateIndividualInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("updateIndividualInfo - " + req.getToken());
		}
		
		return identityController.updateIndividualInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="updateIndividualCertInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> updateIndividualCertInfo(@RequestBody @Validated UpdateIndividualCertInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("updateIndividualCertInfo - " + req.getToken());
		}
		
		return identityController.updateIndividualCertInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="updateEnterpriseCertInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> updateEnterpriseCertInfo(@RequestBody @Validated UpdateEnterpriseCertInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("updateEnterpriseCertInfo - " + req.getToken());
		}
		
		return identityController.updateEnterpriseCertInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="updateEnterpriseInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> updateEnterpriseInfo(@RequestBody @Validated UpdateEnterpriseInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("updateEnterpriseInfo - " + req.getToken());
		}
		
		return identityController.updateEnterpriseInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="updateAvatar", method=RequestMethod.POST)
	public Map<String, String> updateAvatar(@RequestParam("token") String token, @RequestParam("file") MultipartFile file) {
		if (logger.isDebugEnabled()) {
			logger.debug("updateAvatar - " + token);
		}
		
		return identityController.updateAvatar(token, file);
	}
	
	@CrossOrigin
	@RequestMapping(value="cropAvatar", method=RequestMethod.POST)
	public Map<String, String> cropAvatar(@RequestBody @Validated CropAvatarRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("cropAvatar - " + req.getToken());
		}
		
		return identityController.cropAvatar(req.getToken(), req.getAvatarId(), req.getCrop());
	}
	
	@CrossOrigin
	@RequestMapping(value="uploadCertificate", method=RequestMethod.POST)
	public Map<String, String> uploadCertificate(@RequestParam("token") String token, @RequestParam("type") String type, @RequestParam("file") MultipartFile file) {
		if (logger.isDebugEnabled()) {
			logger.debug("uploadCertificate - " + type);
		}
		
		return identityController.uploadCertificate(token, type, file);
	}
	
	@RequestMapping(value="getCertificate", method=RequestMethod.POST, produces="image/jpeg")
	public void getCertificate(@RequestBody @Validated GetCertificateRequest req, HttpServletResponse res) {
		if (logger.isDebugEnabled()) {
			logger.debug("getCertificate - token: " + req.getToken());
		}
		
		try {
			identityController.getCertificate(req, res);
		} catch (IOException e) {
			if (logger.isErrorEnabled()) {
				logger.error("getCertificate - failed to read certificate image file");
			}
		}
	}
	
	@CrossOrigin
	@RequestMapping(value="getCertificate", method=RequestMethod.GET, produces="image/jpeg")
	public void getCertificate(@RequestParam("token") String token, @RequestParam("imageId") String imageId, HttpServletResponse res) throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("GET: getCertificate - token: " + token);
		}
		if (null == token) {
			res.sendError(HttpServletResponse.SC_BAD_REQUEST, "token is missing");
			return;
		}
		
		GetCertificateRequest req = new GetCertificateRequest();
		req.setToken(token);
		req.setImageId(imageId);
		
		try {
			identityController.getCertificate(req, res);
		} catch (IOException e) {
			if (logger.isErrorEnabled()) {
				logger.error("getCertificate - failed to read certificate image file");
			}
		}
	}
	
	@CrossOrigin
	@RequestMapping(value="pendingIndividualInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> pendingIndividualInfo(@RequestBody @Validated PendingIndividualInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("pendingIndividualInfo - token: " + req.getToken());
		}
		
		return identityController.pendingIndividualInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="pendingEnterpriseInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String>pendingEnterpriseInfo(@RequestBody @Validated PendingEnterpriseInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("pendingEnterpriseInfo - token: " + req.getToken());
		}
		
		return identityController.pendingEnterpriseInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="completeIndividualInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> completeIndividualInfo(@RequestBody @Validated CompleteIndividualInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("completeIndividualInfo - token: " + req.getToken());
		}
		
		return identityController.completeIndividualInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="completeEnterpriseInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> completeEnterpriseInfo(@RequestBody @Validated CompleteEnterpriseInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("completeEnterpriseInfo - token: " + req.getToken());
		}
		
		return identityController.completeEnterpriseInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="accountBalance", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> accountBalance(@RequestBody @Validated AccountBalanceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("accountBalance - " + req.getToken());
		}
		
		return identityController.accountBalance(req);
	}
	
	// identity admin
	
	@CrossOrigin
	@RequestMapping(value="adminGetVerificationCode", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> adminGetVerificationCode(@RequestBody @Validated AdminGetVerificationCodeRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("adminGetVerificationCode - " + req.getPhoneNumber());
		}
		
		return adminController.adminGetVerificationCode(req);
	}
	
	
	@CrossOrigin
	@RequestMapping(value="adminSignIn", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> adminSignIn(@RequestBody @Validated AdminSignInRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("adminSignIn - " + req.getPhoneNumber());
		}
		
		return adminController.adminSignIn(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="adminUpdatePassword", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> adminUpdatePassword(@RequestBody @Validated AdminUpdatePasswordRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("adminUpdatePassword - token: " + req.getToken());
		}
		
		return adminController.adminUpdatePassword(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="rejectIndividualPending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> rejectIndividualPending(@RequestBody @Validated RejectIndividualPendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("rejectIndividualPending - token: " + req.getToken());
		}
		
		return adminController.rejectIndividualPending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="approveIndividualPending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> approveIndividualPending(@RequestBody @Validated ApproveIndividualPendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("approveIndividualPending - token: " + req.getToken());
		}
		
		return adminController.approveIndividualPending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="individualPendingList", method=RequestMethod.POST, consumes="application/json")
	public Object individualPendingList(@RequestBody @Validated IndividualPendingListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("individualPendingList - token: " + req.getToken());
		}
		
		return adminController.individualPendingList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="rejectEnterprisePending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> rejectEnterprisePending(@RequestBody @Validated RejectEnterprisePendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("rejectEnterprisePending - token: " + req.getToken());
		}

		return adminController.rejectEnterprisePending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="approveEnterprisePending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> approveEnterprisePending(@RequestBody @Validated ApproveEnterprisePendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("approveEnterprisePending - token: " + req.getToken());
		}
		
		return adminController.approveEnterprisePending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="enterprisePendingList", method=RequestMethod.POST, consumes="application/json")
	public Object enterprisePendingList(@RequestBody @Validated EnterprisePendingListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("enterprisePendingList - token: " + req.getToken());
		}

		return adminController.enterprisePendingList(req);
	}
		
	// product
	
	@CrossOrigin
	@RequestMapping(value="addVehiclePending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> addVehiclePending(@RequestBody @Validated AddVehiclePendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("addVehiclePending - token: " + req.getToken());
		}
		
		return productController.addVehiclePending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="addVehiclePendingResource", method=RequestMethod.POST)
	public Map<String, String> addVehiclePendingResource(@RequestParam("token") String token, @RequestParam("type") String type, @RequestParam("file") MultipartFile file) {
		if (logger.isDebugEnabled()) {
			logger.debug("addVehiclePendingResource - type: " + type);
		}
		
		return productController.addVehiclePendingResource(token, type, file);
	}
	
	@CrossOrigin
	@RequestMapping(value="updateVehicleResource", method=RequestMethod.POST)
	public Map<String, String> updateVehicleResource(@RequestParam("token") String token, @RequestParam("vehicleId") String vehicleId, @RequestParam("type") String type, @RequestParam("file") MultipartFile file) {
		if (logger.isDebugEnabled()) {
			logger.debug("updateVehicleResource - type: " + type);
		}
		
		return productController.updateVehicleResource(token, vehicleId, type, file);
	}
	
	@CrossOrigin
	@RequestMapping(value="cropVehiclePendingResource", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> cropVehiclePendingResource(@RequestBody @Validated CropVehiclePendingResourceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("cropVehiclePendingResource - type: " + req.getType());
		}
		
		return productController.cropVehiclePendingResource(req.getToken(), req.getImageId(), req.getType(), req.getCrop());
	}
	
	@CrossOrigin
	@RequestMapping(value="cropWarehousePendingResource", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> cropWarehousePendingResource(@RequestBody @Validated CropWarehousePendingResourceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("cropWarehousePendingResource - type: " + req.getType());
		}
		
		return productController.cropWarehousePendingResource(req.getToken(), req.getImageId(), req.getType(), req.getCrop());
	}
	
	@CrossOrigin
	@RequestMapping(value="cropProductPendingResource", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> cropProductPendingResource(@RequestBody @Validated CropProductPendingResourceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("cropProductPendingResource - crop: " + req.getCrop());
		}
		
		return productController.cropProductPendingResource(req.getToken(), req.getImageId(), req.getCrop());
	}
	
	@CrossOrigin
	@RequestMapping(value="completeVehiclePending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> completeVehiclePending(@RequestBody @Validated CompleteVehiclePendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("completeVehiclePending - token: " + req.getToken());
		}
		
		return productController.completeVehiclePending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="vehicleResource", method=RequestMethod.GET, produces="image/jpeg")
	public void vehicleResource(@RequestParam("imageId") String imageId, HttpServletResponse res) throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("GET: vehicleResource - imageId: " + imageId);
		}

		VehicleResourceRequest req = new VehicleResourceRequest();
		req.setImageId(imageId);
		
		productController.vehicleResource(req, res);
	}
	
	@CrossOrigin
	@RequestMapping(value="vehicleResource", method=RequestMethod.POST, produces="image/jpeg")
	public void vehicleResource(@RequestBody VehicleResourceRequest req, HttpServletResponse res) throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("POST: vehicleResource - imageId: " + req.getImageId());
		}
		
		productController.vehicleResource(req, res);
	}
	
	@CrossOrigin
	@RequestMapping(value="warehouseResource", method=RequestMethod.GET, produces="image/jpeg")
	public void warehouseResource(@RequestParam("imageId") String imageId, HttpServletResponse res) throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("GET: warehouseResource - imageId: " + imageId);
		}
		
		WarehouseResourceRequest req = new WarehouseResourceRequest();
		req.setImageId(imageId);
		
		productController.warehouseResource(req, res);
	}
	
	@CrossOrigin
	@RequestMapping(value="warehouseResource", method=RequestMethod.POST, produces="image/jpeg")
	public void warehouseResource(@RequestBody WarehouseResourceRequest req, HttpServletResponse res) throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("POST: warehouseResource - imageId: " + req.getImageId());
		}
		
		productController.warehouseResource(req, res);
	}
	
	@CrossOrigin
	@RequestMapping(value="productResource", method=RequestMethod.GET, produces="image/jpeg")
	public void productResource(@RequestParam("imageId") String imageId, HttpServletResponse res) throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("GET: productResource - imageId: " + imageId);
		}
		
		ProductResourceRequest req = new ProductResourceRequest();
		req.setImageId(imageId);
		
		productController.productResource(req, res);
	}
	
	@CrossOrigin
	@RequestMapping(value="productResource", method=RequestMethod.POST, produces="image/jpeg")
	public void productResource(@RequestBody ProductResourceRequest req, HttpServletResponse res) throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("POST: productResource - imageId: " + req.getImageId());
		}
		
		productController.productResource(req, res);
	}
	
	@CrossOrigin
	@RequestMapping(value="inReviewVehiclePendingList", method=RequestMethod.POST, consumes="application/json")
	public Object inReviewPendingList(@RequestBody @Validated InReviewVehiclePendingListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("inReviewPendingList - token: " + req.getToken());
		}
		
		return productController.inReviewPendingList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="inReviewWarehousePendingList", method=RequestMethod.POST, consumes="application/json")
	public Object inReviewWarehousePendingList(@RequestBody @Validated InReviewWarehousePendingListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("inReviewWarehousePendingList - token: " + req.getToken());
		}
		
		return productController.inReviewWarehousePendingList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="inReviewProductPendingList", method=RequestMethod.POST, consumes="application/json")
	public Object inReviewProductPendingList(@RequestBody @Validated InReviewProductPendingListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("inReviewProductPendingList - token: " + req.getToken());
		}
		
		return productController.inReviewProductPendingList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="approvedVehicleList", method=RequestMethod.POST, consumes="application/json")
	public Object approvedVehicleList(@RequestBody @Validated ApprovedVehicleListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("approvedVehicleList - token: " + req.getToken());
		}
		
		return productController.approvedVehicleList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="approvedWarehouseList", method=RequestMethod.POST, consumes="application/json")
	public Object approvedWarehouseList(@RequestBody @Validated ApprovedWarehouseListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("approvedWarehouseList - token: " + req.getToken());
		}
		
		return productController.approvedWarehouseList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="approvedProductList", method=RequestMethod.POST, consumes="application/json")
	public Object approvedProductList(@RequestBody @Validated ApprovedProductListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("approvedProductList - token: " + req.getToken());
		}
		
		return productController.approvedProductList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="rejectedVehicleList", method=RequestMethod.POST, consumes="application/json")
	public Object rejectedVehicleList(@RequestBody @Validated RejectedVehicleListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("rejectedVehicleList - token: " + req.getToken());
		}
		
		return productController.rejectedVehicleList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="rejectedWarehouseList", method=RequestMethod.POST, consumes="application/json")
	public Object rejectedWarehouseList(@RequestBody @Validated RejectedWarehouseListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("rejectedWarehouseList - token: " + req.getToken());
		}
		
		return productController.rejectedWarehouseList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="rejectedProductList", method=RequestMethod.POST, consumes="application/json")
	public Object rejectedProductList(@RequestBody @Validated RejectedProductListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("rejectedProductList - token: " + req.getToken());
		}
		
		return productController.rejectedProductList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="vehicleCounting", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> vehicleCounting(@RequestBody @Validated VehicleCountingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("vehicleCounting - token: " + req.getToken());
		}
		
		return productController.vehicleCounting(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="warehouseCounting", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> warehouseCounting(@RequestBody @Validated WarehouseCountingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("warehouseCounting - token: " + req.getToken());
		}
		
		return productController.warehouseCounting(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="productCounting", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> productCounting(@RequestBody @Validated ProductCountingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("productCounting - token: " + req.getToken());
		}
		
		return productController.productCounting(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="vehicleSpecListing", method=RequestMethod.POST, consumes="application/json")
	public Object vehicleSpecListing(@RequestBody @Validated VehicleSpecListingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("vehicleSpecListing - " + req.getToken());
		}
		
		return productController.vehicleSpecListing(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="warehouseSpecListing", method=RequestMethod.POST, consumes="application/json")
	public Object warehouseSpecListing(@RequestBody @Validated WarehouseSpecListingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("warehouseSpecListing - " + req.getToken());
		}
		
		return productController.warehouseSpecListing(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="productSpecListing", method=RequestMethod.POST, consumes="application/json")
	public Object productSpecListing(@RequestBody @Validated ProductSpecListingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("productSpecListing - " + req.getToken());
		}
		
		return productController.productSpecListing(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="vehicleSpecStock", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> vehicleSpecStock(@RequestBody @Validated VehicleSpecStockRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("vehicleSpecStock - " + req.getToken());
		}
		
		return productController.vehicleSpecStock(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="vehicleServiceListing", method=RequestMethod.POST, consumes="application/json")
	public Object vehicleServiceListing(@RequestBody @Validated VehicleServiceListingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("vehicleServiceListing - " + req.getToken());
		}
		
		return productController.vehicleServiceListing(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="warehouseServiceListing", method=RequestMethod.POST, consumes="application/json")
	public Object warehouseServiceListing(@RequestBody @Validated WarehouseServiceListingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("warehouseServiceListing - " + req.getToken());
		}
		
		return productController.warehouseServiceListing(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="productServiceListing", method=RequestMethod.POST, consumes="application/json")
	public Object productServiceListing(@RequestBody @Validated ProductServiceListingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("productServiceListing - " + req.getToken());
		}
		
		return productController.productServiceListing(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="publishCompleteVehicleService", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> publishCompleteVehicleService(@RequestBody @Validated PublishCompleteVehicleServiceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("publishCompleteVehicleService - token: " + req.getToken());
		}
		
		return productController.publishCompleteVehicleService(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="publishWarehouseService", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> publishWarehouseService(@RequestBody @Validated PublishWarehouseServiceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("publishWarehouseService - token: " + req.getToken());
		}
		
		return productController.publishWarehouseService(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="publishProductService", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> publishProductService(@RequestBody @Validated PublishProductServiceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("publishProductService - token: " + req.getToken());
		}
		
		return productController.publishProductService(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="cancelCompleteVehicleService", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> cancelCompleteVehicleService(@RequestBody @Validated CancelCompleteVehicleServiceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("cancelCompleteVehicleService - token: " + req.getToken());
		}
		
		return productController.cancelCompleteVehicleService(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="cancelWarehouseService", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> cancelWarehouseService(@RequestBody @Validated CancelWarehouseServiceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("cancelWarehouseService - token: " + req.getToken());
		}
		
		return productController.cancelWarehouseService(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="cancelProductService", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> cancelProductService(@RequestBody @Validated CancelProductServiceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("cancelProductService - token: " + req.getToken());
		}
		
		return productController.cancelProductService(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="vehicleInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> vehicleInfo(@RequestBody @Validated VehicleInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("vehicleInfo - token: " + req.getToken());
		}
		
		return productController.vehicleInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="warehouseInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, Object> warehouseInfo(@RequestBody @Validated WarehouseInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("warehouseInfo - token: " + req.getToken());
		}
		
		return productController.warehouseInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="productInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, Object> productInfo(@RequestBody @Validated ProductInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("productInfo - token: " + req.getToken());
		}
		
		return productController.productInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="deleteRejectedVehicle", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> deleteRejectedVehicle(@RequestBody @Validated DeleteRejectedVehicleRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteRejectedVehicle - " + req.getToken());
		}
		
		return productController.deleteRejectedVehicle(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="deleteRejectedWarehouse", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> deleteRejectedWarehouse(@RequestBody @Validated DeleteRejectedWarehouseRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteRejectedWarehouse - token: " + req.getToken());
		}
		
		return productController.deleteRejectedWarehouse(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="deleteRejectedProduct", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> deleteRejectedProduct(@RequestBody @Validated DeleteRejectedProductRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteRejectedProduct - token: " + req.getToken());
		}
		
		return productController.deleteRejectedProduct(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="deleteApprovedVehicle", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> deleteApprovedVehicle(@RequestBody @Validated DeleteApprovedVehicleRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteApprovedVehicle - token: " + req.getToken());
		}
		
		return productController.deleteApprovedVehicle(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="deleteApprovedWarehouse", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> deleteApprovedWarehouse(@RequestBody @Validated DeleteApprovedWarehouseRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteApprovedWarehouse - token: " + req.getToken());
		}
		
		return productController.deleteApprovedWarehouse(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="deleteApprovedProduct", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> deleteApprovedProduct(@RequestBody @Validated DeleteApprovedProductRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteApprovedProduct - token: " + req.getToken());
		}
		
		return productController.deleteApprovedProduct(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="updateVehicleInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> updateVehicleInfo(@RequestBody @Validated UpdateVehicleInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("updateVehicleInfo - " + req.getToken());
		}
		
		return productController.updateVehicleInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="updateWarehouseInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> updateWarehouseInfo(@RequestBody @Validated UpdateWarehouseInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("updateWarehouseInfo - token: " + req.getToken());
		}
		
		return productController.updateWarehouseInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="updateProductInfo", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> updateProductInfo(@RequestBody @Validated UpdateProductInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("updateProductInfo - token: " + req.getToken());
		}
		
		return productController.updateProductInfo(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="addDriver", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> addDriver(@RequestBody @Validated AddDriverRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("addDriver - token: " + req.getToken());
		}
		
		return productController.addDriver(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="addDriverResource", method=RequestMethod.POST)
	public Map<String, String> addDriverResource(@RequestParam("token") String token, @RequestParam("type") String type, @RequestParam("file") MultipartFile file) {
		if (logger.isDebugEnabled()) {
			logger.debug("addDriverResource - token: " + token);
		}
		
		return productController.addDriverResource(token, type, file);
	}
	
	@CrossOrigin
	@RequestMapping(value="driverResource", method=RequestMethod.GET, produces="image/jpeg")
	public void driverResource(@RequestParam("token") String token, @RequestParam("imageId") String imageId, HttpServletResponse res) throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("driverResource - token: " + token);
		}
		
		if (null == token) {
			res.sendError(HttpServletResponse.SC_BAD_REQUEST, "token is missing");
			return;
		}
		
		DriverResourceRequest req = new DriverResourceRequest();
		req.setToken(token);
		req.setImageId(imageId);
		
		productController.driverResource(req, res);
	}
	
	@CrossOrigin
	@RequestMapping(value="driverResource", method=RequestMethod.POST, produces="image/jpeg")
	public void driverResource(@RequestBody @Validated DriverResourceRequest req, HttpServletResponse res) throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("driverResource - token: " + req.getToken());
		}
		
		productController.driverResource(req, res);
	}
	
	@CrossOrigin
	@RequestMapping(value="driverListing", method=RequestMethod.POST, consumes="application/json")
	public Object driverListing(@RequestBody @Validated DriverListingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("driverListing - token: " + req.getToken());
		}
		
		return productController.driverListing(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="updateDriver", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> updateDriver(@RequestBody @Validated UpdateDriverRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("updateDriver - token: " + req.getToken());
		}
		
		return productController.updateDriver(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="deleteDriver", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> deleteDriver(@RequestBody @Validated DeleteDriverRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteDriver - token: " + req.getToken());
		}
		
		return productController.deleteDriver(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="searchCompleteVehicleService", method=RequestMethod.POST, consumes="application/json")
	public List<Map<String, Object>> searchCompleteVehicleService(@RequestBody SearchCompleteVehicleServiceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("searchCompleteVehicleService");
		}
		
		return productController.searchCompleteVehicleService(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="completeVehicleServiceCounting", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> completeVehicleServiceCounting(@RequestBody CompleteVehicleServiceCountingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("completeVehicleServiceCounting");
		}
		
		return productController.completeVehicleServiceCounting(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="searchWarehouseService", method=RequestMethod.POST, consumes="application/json")
	public List<Map<String, Object>> searchWarehouseService(@RequestBody SearchWarehouseServiceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("SearchWarehouseServiceRequest");
		}
		
		return productController.searchWarehouseService(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="warehouseServiceCounting", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> warehouseServiceCounting(@RequestBody WarehouseServiceCountingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("warehouseServiceCounting");
		}
		
		return productController.warehouseServiceCounting(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="searchProductService", method=RequestMethod.POST, consumes="application/json")
	public List<Map<String, Object>> searchProductService(@RequestBody SearchProductServiceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("searchProductService");
		}
		
		return productController.searchProductService(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="productServiceCounting", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> productServiceCounting(@RequestBody ProductServiceCountingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("productServiceCounting");
		}
		
		return productController.productServiceCounting(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="vehiclesForCompleteVehicleService", method=RequestMethod.POST, consumes="application/json")
	public List<Map<String, Object>> vehiclesForCompleteVehicleService(@RequestBody VehiclesForCompleteVehicleServiceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("vehiclesForCompleteVehicleService - " + req.getId());
		}
		
		return productController.vehiclesForCompleteVehicleService(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="warehouseForWarehouseService", method=RequestMethod.POST, consumes="application/json")
	public Map<String, Object> warehouseForWarehouseService(@RequestBody WarehouseForWarehouseServiceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("warehouseForWarehouseService - " + req.getId());
		}
		
		return productController.warehouseForWarehouseService(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="productForProductService", method=RequestMethod.POST, consumes="application/json")
	public Map<String, Object> productForProductService(@RequestBody ProductForProductServiceRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("ProductForProductServiceRequest - " + req.getId());
		}
		
		return productController.productForProductService(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="addWarehousePending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> addWarehousePending(@RequestBody @Validated AddWarehousePendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("addWarehousePending - " + req.getToken());
		}
		
		return productController.addWarehousePending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="addProductPending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> addProductPending(@RequestBody @Validated AddProductPendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("addProductPending - " + req.getToken());
		}
		
		return productController.addProductPending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="completeWarehousePending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> completeWarehousePending(@RequestBody @Validated CompleteWarehousePendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("completeWarehousePending - " + req.getToken());
		}
		
		return productController.completeWarehousePending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="completeProductPending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> completeProductPending(@RequestBody @Validated CompleteProductPendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("completeProductPending - " + req.getToken());
		}
		
		return productController.completeProductPending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="addWarehousePendingResource", method=RequestMethod.POST)
	public Map<String, String> addWarehousePendingResource(@RequestParam("token") String token, @RequestParam("type") String type, @RequestParam("file") MultipartFile file) {
		if (logger.isDebugEnabled()) {
			logger.debug("addWarehousePendingResource - type: " + type);
		}
		
		return productController.addWarehousePendingResource(token, type, file);
	}
	
	@CrossOrigin
	@RequestMapping(value="addProductPendingResource", method=RequestMethod.POST)
	public Map<String, String> addProductPendingResource(@RequestParam("token") String token, @RequestParam("type") String type, @RequestParam("file") MultipartFile file) {
		if (logger.isDebugEnabled()) {
			logger.debug("addProductPendingResource - type: " + type);
		}
		
		return productController.addProductPendingResource(token, type, file);
	}
	
	// product admin
	
	@CrossOrigin
	@RequestMapping(value="vehiclePendingList", method=RequestMethod.POST, consumes="application/json")
	public Object vehiclePendingList(@RequestBody @Validated VehiclePendingListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("vehiclePendingList - " + req.getToken());
		}
		
		return adminController.vehiclePendingList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="warehousePendingList", method=RequestMethod.POST, consumes="application/json")
	public Object warehousePendingList(@RequestBody @Validated WarehousePendingListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("warehousePendingList - " + req.getToken());
		}
		
		return adminController.warehousePendingList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="productPendingList", method=RequestMethod.POST, consumes="application/json")
	public Object productPendingList(@RequestBody @Validated ProductPendingListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("productPendingList - " + req.getToken());
		}
		
		return adminController.productPendingList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="rejectVehiclePending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> rejectVehiclePending(@RequestBody @Validated RejectVehiclePendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("rejectVehiclePending - " + req.getToken());
		}
		
		return adminController.rejectVehiclePending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="rejectWarehousePending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> rejectWarehousePending(@RequestBody @Validated RejectWarehousePendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("rejectWarehousePending - " + req.getToken());
		}
		
		return adminController.rejectWarehousePending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="rejectProductPending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> rejectProductPending(@RequestBody @Validated RejectProductPendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("rejectProductPending - " + req.getToken());
		}
		
		return adminController.rejectProductPending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="approveVehiclePending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> approveVehiclePending(@RequestBody @Validated ApproveVehiclePendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("approveVehiclePending - " + req.getToken());
		}
		return adminController.approveVehiclePending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="approveWarehousePending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> approveWarehousePending(@RequestBody @Validated ApproveWarehousePendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("approveWarehousePending - " + req.getToken());
		}
		
		return adminController.approveWarehousePending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="approveProductPending", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> approveProductPending(@RequestBody @Validated ApproveProductPendingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("approveProductPending - " + req.getToken());
		}
		
		return adminController.approveProductPending(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="vehicleBindingRequestList", method=RequestMethod.POST, consumes="application/json")
	public Object vehicleBindingRequestList(@RequestBody @Validated VehicleBindingRequestListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("vehicleBindingRequestList - " + req.getToken());
		}
		
		return adminController.vehicleBindingRequestList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="addNoteToVehicleBindingRequest", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> addNoteToVehicleBindingRequest(@RequestBody @Validated AddNoteToVehicleBindingRequestRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("addNoteToVehicleBindingRequest - " + req.getToken());
		}
		
		return adminController.addNoteToVehicleBindingRequest(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="processedVehicleBindingRequest", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> processedVehicleBindingRequest(@RequestBody @Validated ProcessedVehicleBindingRequestRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("processedVehicleBindingRequest - " + req.getToken());
		}
		
		return adminController.processedVehicleBindingRequest(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="warehouseBindingRequestList", method=RequestMethod.POST, consumes="application/json")
	public Object warehouseBindingRequestList(@RequestBody @Validated WarehouseBindingRequestListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("warehouseBindingRequestList - " + req.getToken());
		}
		
		return adminController.warehouseBindingRequestList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="addNoteToWarehouseBindingRequest", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> addNoteToWarehouseBindingRequest(@RequestBody @Validated AddNoteToWarehouseBindingRequestRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("addNoteToWarehouseBindingRequest - " + req.getToken());
		}
		
		return adminController.addNoteToWarehouseBindingRequest(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="processedWarehouseBindingRequest", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> processedWarehouseBindingRequest(@RequestBody @Validated ProcessedWarehouseBindingRequestRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("processedWarehouseBindingRequest - " + req.getToken());
		}
		
		return adminController.processedWarehouseBindingRequest(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="bindVehicle", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> bindVehicle(@RequestBody @Validated BindVehicleRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("bindVehicle - " + req.getToken());
		}
		
		return adminController.bindVehicle(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="queryVehicle", method=RequestMethod.POST, consumes="application/json")
	public Object queryVehicle(@RequestBody @Validated QueryVehicleRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("QueryVehicleRequest - " + req.getToken());
		}
		
		return adminController.queryVehicle(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="bindWarehouse", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> bindWarehouse(@RequestBody @Validated BindWarehouseRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("bindWarehouse - " + req.getToken());
		}
		
		return adminController.bindWarehouse(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="queryWarehouse", method=RequestMethod.POST, consumes="application/json")
	public Object queryWarehouse(@RequestBody @Validated QueryWarehouseRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("queryWarehouse - " + req.getToken());
		}
		
		return adminController.queryWarehouse(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="queryProduct", method=RequestMethod.POST, consumes="application/json")
	public Object queryProduct(@RequestBody @Validated QueryProductRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("queryProduct - " + req.getToken());
		}
		
		return adminController.queryProduct(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="listUsers", method=RequestMethod.POST, consumes="application/json")
	public Object listUsers(@RequestBody @Validated ListUsersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("listUsers - " + req.getToken());
		}
		
		return adminController.listUsers(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="listIndividualUsers", method=RequestMethod.POST, consumes="application/json")
	public Object listIndividualUsers(@RequestBody @Validated ListIndividualUsersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("listIndividualUsers - " + req.getToken());
		}
		
		return adminController.listIndividualUsers(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="filterIndividualUsers", method=RequestMethod.POST, consumes="application/json")
	public Object filterIndividualUsers(@RequestBody @Validated FilterIndividualUsersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("filterIndividualUsers - " + req.getToken());
		}
		
		return adminController.filterIndividualUsers(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="filterEnterpriseUsers", method=RequestMethod.POST, consumes="application/json")
	public Object filterEnterpriseUsers(@RequestBody @Validated FilterIndividualUsersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("filterEnterpriseUsers - " + req.getToken());
		}
		
		return adminController.filterEnterpriseUsers(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="filterVehicles", method=RequestMethod.POST, consumes="application/json")
	public Object filterVehicles(@RequestBody @Validated FilterIndividualUsersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("filterVehicles - " + req.getToken());
		}
		
		return adminController.filterVehicles(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="filterWarehouses", method=RequestMethod.POST, consumes="application/json")
	public Object filterWarehouses(@RequestBody @Validated FilterIndividualUsersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("filterWarehouses - " + req.getToken());
		}
		
		return adminController.filterWarehouses(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="filterProducts", method=RequestMethod.POST, consumes="application/json")
	public Object filterProducts(@RequestBody @Validated FilterIndividualUsersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("filterProducts - " + req.getToken());
		}
		
		return adminController.filterProducts(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="queryIndividualUsers", method=RequestMethod.POST, consumes="application/json")
	public Object queryIndividualUsers(@RequestBody @Validated QueryIndividualUsersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("queryIndividualUsers - " + req.getToken());
		}
		
		return adminController.queryIndividualUsers(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="queryEnterpriseUsers", method=RequestMethod.POST, consumes="application/json")
	public Object queryEnterpriseUsers(@RequestBody @Validated QueryIndividualUsersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("queryEnterpriseUsers - " + req.getToken());
		}
		
		return adminController.queryEnterpriseUsers(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="listEnterpriseUsers", method=RequestMethod.POST, consumes="application/json")
	public Object listEnterpriseUsers(@RequestBody @Validated ListEnterpriseUsersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("listEnterpriseUsers - " + req.getToken());
		}
		
		return adminController.listEnterpriseUsers(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="listAppealRequests", method=RequestMethod.POST, consumes="application/json")
	public Object listAppealRequests(@RequestBody @Validated ListAppealRequestsRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("listAppealRequests - " + req.getToken());
		}
		
		return adminController.listAppealRequests(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="resolvedAppealList", method=RequestMethod.POST, consumes="application/json")
	public Object resolvedAppealList(@RequestBody @Validated ResolvedAppealListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("resolvedAppealList - " + req.getToken());
		}
		
		return adminController.resolvedAppealList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="queryUser", method=RequestMethod.POST, consumes="application/json")
	public Object queryUser(@RequestBody @Validated QueryUserRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("queryUser - " + req.getToken());
		}
		
		return adminController.queryUser(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="queryOnlineVehicles", method=RequestMethod.POST, consumes="application/json")
	public Object queryOnlineVehicles(@RequestBody @Validated QueryOnlineVehiclesRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("queryOnlineVehicles - " + req.getToken());
		}
		
		return adminController.queryOnlineVehicles(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="queryVehicleOrders", method=RequestMethod.POST, consumes="application/json")
	public Object queryVehicleOrders(@RequestBody @Validated QueryVehicleOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("queryVehicleOrders - " + req.getToken());
		}
		
		return adminController.queryVehicleOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="infoUpdateForAdminConsole", method=RequestMethod.POST, consumes="application/json")
	public Object infoUpdateForAdminConsole(@RequestBody @Validated InfoUpdateForAdminConsoleRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("infoUpdateForAdminConsole - " + req.getToken());
		}
		
		return adminController.infoUpdateForAdminConsole(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="queryOnlineWarehouse", method=RequestMethod.POST, consumes="application/json")
	public Object queryOnlineWarehouse(@RequestBody @Validated QueryOnlineWarehouseRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("queryOnlineWarehouse - " + req.getToken());
		}
		
		return adminController.queryOnlineWarehouse(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="addIdentityTemplate", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> addIdentityTemplate(@RequestBody @Validated AddIdentityTemplateRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("addIdentityTemplate - " + req.getToken());
		}
		
		return adminController.addIdentityTemplate(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="addServiceTemplate", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> addServiceTemplate(@RequestBody @Validated AddServiceTemplateRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("addServiceTemplate - " + req.getToken());
		}
		
		return adminController.addServiceTemplate(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="deleteIdentityTemplate", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> deleteIdentityTemplate(@RequestBody @Validated DeleteIdentityTemplateRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteIdentityTemplate - " + req.getToken());
		}
		
		return adminController.deleteIdentityTemplate(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="deleteServiceTemplate", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> deleteServiceTemplate(@RequestBody @Validated DeleteServiceTemplateRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteServiceTemplate - " + req.getToken());
		}
		
		return adminController.deleteServiceTemplate(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="withdrawRequestList", method=RequestMethod.POST, consumes="application/json")
	public Object withdrawRequestList(@RequestBody @Validated WithdrawRequestListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("withdrawRequestList - " + req.getToken());
		}
		
		return adminController.withdrawRequestList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="approveWithdrawRequest", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> approveWithdrawRequest(@RequestBody @Validated ApproveWithdrawRequestRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("approveWithdrawRequest - " + req.getToken());
		}
		
		return adminController.approveWithdrawRequest(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="rejectWithdrawRequest", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> rejectWithdrawRequest(@RequestBody @Validated RejectWithdrawRequestRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("rejectWithdrawRequest - " + req.getToken());
		}
		
		return adminController.rejectWithdrawRequest(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="identityTemplateList", method=RequestMethod.POST, consumes="application/json")
	public Object identityTemplateList(@RequestBody @Validated IdentityTemplateListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("identityTemplateList - " + req.getToken());
		}
		
		return adminController.identityTemplateList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="serviceTemplateList", method=RequestMethod.POST, consumes="application/json")
	public Object serviceTemplateList(@RequestBody @Validated ServiceTemplateListRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("serviceTemplateList - " + req.getToken());
		}
		
		return adminController.serviceTemplateList(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="resolveAppeal", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> resolveAppeal(@RequestBody @Validated ResolveAppealRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("resolveAppeal - " + req.getToken());
		}
		
		return adminController.resolveAppeal(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="heartbeatMockup", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> heartbeatMockup(@RequestBody @Validated HeartbeatMockupRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("heartbeatMockup - " + req.getToken());
		}
		
		return adminController.heartbeatMockup(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="locationMockup", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> locationMockup(@RequestBody @Validated LocationMockupRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("locationMockup - " + req.getToken());
		}
		
		return adminController.locationMockup(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="temperatureMockup", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> temperatureMockup(@RequestBody @Validated TemperatureMockupRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("temperatureMockup - " + req.getToken());
		}
		
		return adminController.temperatureMockup(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="humidityMockup", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> humidityMockup(@RequestBody @Validated HumidityMockupRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("humidityMockup - " + req.getToken());
		}
		
		return adminController.humidityMockup(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="mockupResult", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> mockupResult(@RequestBody @Validated MockupResultRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("mockupResult - " + req.getToken());
		}
		
		return adminController.mockupResult(req);
	}
	
	// order management
	@CrossOrigin
	@RequestMapping(value="createOrder", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> createOrder(@RequestBody @Validated CreateOrderRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("createOrder - " + req.getToken());
		}
		
		return orderController.createOrder(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="orderPaymentRequest", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> orderPaymentRequest(@RequestBody @Validated OrderPaymentRequestRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("orderPaymentRequest - " + req.getToken());
		}
		
		return orderController.orderPaymentRequest(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="deleteOrder", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> deleteOrder(@RequestBody @Validated DeleteOrderRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteOrder - " + req.getToken());
		}
		
		return orderController.deleteOrder(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="alipayNotified", method=RequestMethod.POST)
	public String alipayNotified(HttpServletRequest req) {
		Map<String, String> reqMap = new HashMap<String, String>();
		Map<String, String[]> requestParams = req.getParameterMap();
		for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			reqMap.put(name, valueStr);
		}	
		String out_trade_no = reqMap.get("out_trade_no");
		logger.debug("out_trade_no: " + out_trade_no);
		String trade_no = reqMap.get("trade_no");
		logger.debug("trade_no: " + trade_no);
		String trade_status = reqMap.get("trade_status");
		logger.debug("trade_status: " + trade_status);
		if (AlipayNotify.verify(reqMap)) {
			if (trade_status.equals("TRADE_SUCCESS")) {
				logger.info("payment cleared for internal order number: " + out_trade_no);
				orderController.orderPaid(reqMap);
			}
		} else {
			logger.error("alipayNotified - failed to verify result");
		}
		
		return "success";
	}
	
	@CrossOrigin
	@RequestMapping(value="perOrderAlipayNotified", method=RequestMethod.POST)
	public String perOrderAlipayNotified(HttpServletRequest req) {
		Map<String, String> reqMap = new HashMap<String, String>();
		Map<String, String[]> requestParams = req.getParameterMap();
		for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			reqMap.put(name, valueStr);
		}	
		String out_trade_no = reqMap.get("out_trade_no");
		logger.debug("out_trade_no: " + out_trade_no);
		String trade_no = reqMap.get("trade_no");
		logger.debug("trade_no: " + trade_no);
		String trade_status = reqMap.get("trade_status");
		logger.debug("trade_status: " + trade_status);
		if (AlipayNotify.verify(reqMap)) {
			if (trade_status.equals("TRADE_SUCCESS")) {
				logger.info("payment cleared for internal order number: " + out_trade_no);
				orderController.specificOrderPaid(reqMap);
			}
		} else {
			logger.error("perOrderAlipayNotified - failed to verify result");
		}
		
		return "success";
	}
	
	@CrossOrigin
	@RequestMapping(value="withdrawNotified", method=RequestMethod.POST)
	public String withdrawNotified(HttpServletRequest req) {
		Map<String, String> reqMap = new HashMap<String, String>();
		Map<String, String[]> requestParams = req.getParameterMap();
		for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			reqMap.put(name, valueStr);
		}	
		String batch_no = reqMap.get("batch_no");
		logger.debug("batch_no: " + batch_no);
		String fail_details = reqMap.get("fail_details");
		logger.debug("fail_details: " + fail_details);
		logger.debug("success_details:" + reqMap.get("success_details"));
		if (AlipayNotify.verify(reqMap)) {
			if (null != fail_details) {
				logger.info("withdraw completed for batch number: " + batch_no);
				identityController.withdrawRequestCompleted(batch_no);
			} else {
				logger.info("withdraw failed for batch number: " + batch_no);
				identityController.withdrawRequestFailed(batch_no);
			}
		} else {
			logger.error("perOrderAlipayNotified - failed to verify result");
		}
		return "success";
	}
	
	@CrossOrigin
	@RequestMapping(value="unpaidWarehouseOrders", method=RequestMethod.POST, consumes="application/json")
	public Object unpaidWarehouseOrders(@RequestBody @Validated UnpaidWarehouseOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("unpaidWarehouseOrders - " + req.getToken());
		}
		
		return orderController.unpaidWarehouseOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="loadPendingWarehouseOrders", method=RequestMethod.POST, consumes="application/json")
	public Object loadPendingWarehouseOrders(@RequestBody @Validated LoadPendingWarehouseOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("loadPendingWarehouseOrders - " + req.getToken());
		}
		
		return orderController.loadPendingWarehouseOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="sellerLoadedWarehouseOrder", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> sellerLoadedWarehouseOrder(@RequestBody @Validated SellerLoadedWarehouseOrderRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("sellerLoadedWarehouseOrder - " + req.getToken());
		}
		
		return orderController.sellerLoadedWarehouseOrder(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="loadedWarehouseOrders", method=RequestMethod.POST, consumes="application/json")
	public Object loadedWarehouseOrders(@RequestBody @Validated LoadedWarehouseOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("loadedWarehouseOrders - " + req.getToken());
		}
		
		return orderController.loadedWarehouseOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="sellerOffloadWarehouseOrder", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> sellerOffloadWarehouseOrder(@RequestBody @Validated SellerOffloadWarehouseOrderRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("sellerOffloadWarehouseOrder - " + req.getToken());
		}
		
		return orderController.sellerOffloadWarehouseOrder(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="reviewPendingWarehouseOrders", method=RequestMethod.POST, consumes="application/json")
	public Object reviewPendingWarehouseOrders(@RequestBody @Validated ReviewPendingWarehouseOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("reviewPendingWarehouseOrders - " + req.getToken());
		}
		
		return orderController.reviewPendingWarehouseOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="writeWarehouseOrderReview", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> writeWarehouseOrderReview(@RequestBody @Validated WriteWarehouseOrderReviewRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("writeWarehouseOrderReview - " + req.getToken());
		}
		
		return orderController.writeWarehouseOrderReview(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="completedWarehouseOrders", method=RequestMethod.POST, consumes="application/json")
	public Object completedWarehouseOrders(@RequestBody @Validated CompletedWarehouseOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("completedWarehouseOrders - " + req.getToken());
		}
		
		return orderController.completedWarehouseOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="shipPendingProductOrders", method=RequestMethod.POST, consumes="application/json")
	public Object shipPendingProductOrders(@RequestBody @Validated ShipPendingProductOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("shipPendingProductOrders - " + req.getToken());
		}
		
		return orderController.shipPendingProductOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="transportPendingVehicleOrders", method=RequestMethod.POST, consumes="application/json")
	public Object transportPendingVehicleOrders(@RequestBody @Validated TransportPendingVehicleOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("transportPendingVehicleOrders - " + req.getToken());
		}
		
		return orderController.transportPendingVehicleOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="sellerAssignVehicleToVehicleOrder", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> sellerAssignVehicleToVehicleOrder(@RequestBody @Validated SellerAssignVehicleToVehicleOrderRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("sellerAssignVehicleToVehicleOrder - " + req.getToken());
		}
		
		return orderController.sellerAssignVehicleToVehicleOrder(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="sellerTransportsVehicleOrder", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> sellerTransportsVehicleOrder(@RequestBody @Validated SellerTransportsVehicleOrderRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("sellerTransportsVehicleOrder - " + req.getToken());
		}
		
		return orderController.sellerTransportsVehicleOrder(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="transportOnGoingVehicleOrders", method=RequestMethod.POST, consumes="application/json")
	public Object transportOnGoingVehicleOrders(@RequestBody @Validated TransportOnGoingVehicleOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("transportOnGoingVehicleOrders - " + req.getToken());
		}
		
		return orderController.transportOnGoingVehicleOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="sellerTransportedVehicleOrder", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> sellerTransportedVehicleOrder(@RequestBody @Validated SellerTransportedVehicleOrderRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("sellerTransportedVehicleOrder - " + req.getToken());
		}
		
		return orderController.sellerTransportedVehicleOrder(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="reviewPendingVehicleOrders", method=RequestMethod.POST, consumes="application/json")
	public Object reviewPendingVehicleOrders(@RequestBody @Validated ReviewPendingVehicleOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("reviewPendingVehicleOrders - " + req.getToken());
		}
		
		return orderController.reviewPendingVehicleOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="writeVehicleOrderReview", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> writeVehicleOrderReview(@RequestBody @Validated WriteVehicleOrderReviewRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("writeVehicleOrderReview - " + req.getToken());
		}
		
		return orderController.writeVehicleOrderReview(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="completedVehicleOrders", method=RequestMethod.POST, consumes="application/json")
	public Object completedVehicleOrders(@RequestBody @Validated CompletedVehicleOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("completedVehicleOrders - " + req.getToken());
		}
		
		return orderController.completedVehicleOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="unpaidProductOrders", method=RequestMethod.POST, consumes="application/json")
	public Object unpaidProductOrders(@RequestBody @Validated UnpaidProductOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("unpaidProductOrders - " + req.getToken());
		}
		
		return orderController.unpaidProductOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="unpaidVehicleOrders", method=RequestMethod.POST, consumes="application/json")
	public Object unpaidVehicleOrders(@RequestBody @Validated UnpaidVehicleOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("unpaidVehicleOrders - " + req.getToken());
		}
		
		return orderController.unpaidVehicleOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="sellerShippedProductOrder", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> sellerShippedProductOrder(@RequestBody @Validated SellerShippedProductOrderRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("sellerShippedProductOrder - " + req.getToken());
		}
		
		return orderController.sellerShippedProductOrder(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="shippedProductOrders", method=RequestMethod.POST, consumes="application/json")
	public Object shippedProductOrders(@RequestBody @Validated ShippedProductOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("shippedProductOrders - " + req.getToken());
		}
		
		return orderController.shippedProductOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="reviewPendingProductOrders", method=RequestMethod.POST, consumes="application/json")
	public Object reviewPendingProductOrders(@RequestBody @Validated ReviewPendingProductOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("reviewPendingProductOrders - " + req.getToken());
		}
		
		return orderController.reviewPendingProductOrders(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="completedProductOrders", method=RequestMethod.POST, consumes="application/json")
	public Object completedProductOrders(@RequestBody @Validated CompletedProductOrdersRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("completedProductOrders - " + req.getToken());
		}
		
		return orderController.completedProductOrders(req);
	}
		
	@CrossOrigin
	@RequestMapping(value="buyerReceivedProductOrder", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> buyerReceivedProductOrder(@RequestBody @Validated BuyerReceivedProductOrderRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("buyerReceivedProductOrder - " + req.getToken());
		}
		
		return orderController.buyerReceivedProductOrder(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="writeProductOrderReview", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> writeProductOrderReview (@RequestBody @Validated WriteProductOrderReviewRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("writeProductOrderReview - " + req.getToken());
		}
		
		return orderController.writeProductOrderReview(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="overallProductOrderCounting", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> overallProductOrderCounting(@RequestBody @Validated OverallProductOrderCountingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("overallProductOrderCounting - " + req.getToken());
		}
		
		return orderController.overallProductOrderCounting(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="overallWarehouseOrderCounting", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> overallWarehouseOrderCounting(@RequestBody @Validated OverallWarehouseOrderCountingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("overallWarehouseOrderCounting - " + req.getToken());
		}
		
		return orderController.overallWarehouseOrderCounting(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="overallVehicleOrderCounting", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> overallVehicleOrderCounting(@RequestBody @Validated OverallVehicleOrderCountingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("overallVehicleOrderCounting - " + req.getToken());
		}
		
		return orderController.overallVehicleOrderCounting(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="transactionListing", method=RequestMethod.POST, consumes="application/json")
	public Object transactionListing(@RequestBody @Validated TransactionListingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("transactionListing - " + req.getToken());
		}
		
		return orderController.transactionListing(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="sellerReviewListing", method=RequestMethod.POST, consumes="application/json")
	public Object sellerReviewListing(@RequestBody SellerReviewListingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("sellerReviewListing");
		}
		
		return orderController.sellerReviewListing(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="submitAppealRequest", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> submitAppealRequest(@RequestBody @Validated SubmitAppealRequestRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("submitAppealRequest - " + req.getToken());
		}
		
		return orderController.submitAppealRequest(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="markOrderAsPaid", method=RequestMethod.GET)
	public Map<String, String> markOrderAsPaid(@RequestParam("token") String token, @RequestParam("orderId") String orderId) {
		return null;
//		return orderController.markOrderAsPaid(token, orderId);
	}
	
	@CrossOrigin
	@RequestMapping(value="orderInfo", method=RequestMethod.POST, consumes="application/json")
	public Object orderInfo(@RequestBody @Validated OrderInfoRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("orderInfo - " + req.getToken());
		}
		
		return orderController.orderInfo(req);
	}
	
	// shopping cart
	
	@CrossOrigin
	@RequestMapping(value="addWarehouseIntoCart", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> addWarehouseIntoCart(@RequestBody @Validated AddWarehouseIntoCartRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("addWarehouseIntoCart - " + req.getToken());
		}
		
		return cartController.addWarehouseIntoCart(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="addProductIntoCart", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> addProductIntoCart(@RequestBody @Validated AddProductIntoCartRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("addProductIntoCart - " + req.getToken());
		}
		
		return cartController.addProductIntoCart(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="addVehicleIntoCart", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> addVehicleIntoCart(@RequestBody @Validated AddVehicleIntoCartRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("addVehicleIntoCart - " + req.getToken());
		}
		
		return cartController.addVehicleIntoCart(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="myCart", method=RequestMethod.POST, consumes="application/json")
	public Object myCart(@RequestBody @Validated MyCartRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("myCart - " + req.getToken());
		}
		
		return cartController.myCart(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="deleteServicesFromCart", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> deleteServicesFromCart(@RequestBody @Validated DeleteServicesFromCartRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteServicesFromCart - " + req.getToken());
		}
		
		return cartController.deleteServicesFromCart(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="myCartCounting", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> myCartCounting(@RequestBody @Validated MyCartCountingRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("myCartCounting - " + req.getToken());
		}
		
		return cartController.myCartCounting(req);
	}
	
	// device management
	
	@CrossOrigin
	@RequestMapping(value="vehicleBindingRequest", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> vehicleBindingRequest(@RequestBody @Validated VehicleBindingRequestRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("vehicleBindingRequest - " + req.getToken());
		}
		
		return deviceController.vehicleBindingRequest(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="warehouseBindingRequest", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> warehouseBindingRequest(@RequestBody @Validated WarehouseBindingRequestRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("warehouseBindingRequest - " + req.getToken());
		}
		
		return deviceController.warehouseBindingRequest(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="vehicleLocationDocument", method=RequestMethod.POST, consumes="application/json")
	public Object vehicleLocationDocument(@RequestBody @Validated VehicleLocationDocumentRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("vehicleLocationDocument - " + req.getToken());
		}
		
		return deviceController.vehicleLocationDocument(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="queryVehicleLocationDocument", method=RequestMethod.POST, consumes="application/json")
	public Object queryVehicleLocationDocument(@RequestBody @Validated VehicleLocationDocumentRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("queryVehicleLocationDocument - " + req.getToken());
		}
		return adminController.queryVehicleLocationDocument(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="vehicleTemperatureDocument", method=RequestMethod.POST, consumes="application/json")
	public Object vehicleTemperatureDocument(@RequestBody @Validated VehicleTemperatureDocumentRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("vehicleTemperatureDocument - " + req.getToken());
		}
		
		return deviceController.vehicleTemperatureDocument(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="vehicleHumidityDocument", method=RequestMethod.POST, consumes="application/json")
	public Object vehicleHumidityDocument(@RequestBody @Validated VehicleHumidityDocumentRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("vehicleHumidityDocument - " + req.getToken());
		}
		
		return deviceController.vehicleHumidityDocument(req);
	}
	
	// common data
	
	@CrossOrigin
	@RequestMapping(value="transportationTemperatureLevels", method=RequestMethod.POST, consumes="application/json")
	public List<Map<String, String>> transportationTemperatureLevels() {
		return productController.transportationTemperatureLevels();
	}
	
	@CrossOrigin
	@RequestMapping(value="vehicleLengthDef", method=RequestMethod.POST, consumes="application/json")
	public List<Map<String, String>> vehicleLengthDef() {
		return productController.vehicleLengthDef();
	}
	
	@CrossOrigin
	@RequestMapping(value="warehouseTemperatureLevels", method=RequestMethod.POST, consumes="application/json")
	public List<Map<String, String>> warehouseTemperatureLevels() {
		return productController.warehouseTemperatureLevels();
	}
	
	@CrossOrigin
	@RequestMapping(value="productCategories", method=RequestMethod.POST, consumes="application/json")
	public List<Map<String, String>> productCategories() {
		return productController.productCategories();
	}
	
	// message
	
	@CrossOrigin
	@RequestMapping(value="listMessages", method=RequestMethod.POST, consumes="application/json")
	public Object listMessages(@RequestBody @Validated ListMessagesRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("listMessages - " + req.getToken());
		}
		
		return messageController.listMessages(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="unreadMessageCount", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> unreadMessageCount(@RequestBody @Validated UnreadMessageCountRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("unreadMessageCount - " + req.getToken());
		}
		
		return messageController.unreadMessageCount(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="readMessages", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> readMessages(@RequestBody @Validated ReadMessagesRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("readMessages - " + req.getToken());
		}
		
		return messageController.readMessages(req);
	}
	
	@CrossOrigin
	@RequestMapping(value="deleteMessages", method=RequestMethod.POST, consumes="application/json")
	public Map<String, String> deleteMessages(@RequestBody @Validated DeleteMessagesRequest req) {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteMessages - " + req.getToken());
		}
		
		return messageController.deleteMessages(req);
	}
	
	// maintenance 
	@RequestMapping(value="dataCleanUp", method=RequestMethod.GET)
	public void dataCleanUp(HttpServletRequest req, HttpServletResponse res) throws IOException {
		String clientIP = adminController.clientIp(req);
		if (logger.isInfoEnabled()) {
			logger.info("dataCleanUp called from - " + clientIP);
		}
		if (0 != clientIP.compareTo("127.0.0.1")) {
			res.sendError(HttpServletResponse.SC_FORBIDDEN, "cannot be called form " + clientIP);
			return;
		}
		
		maintenanceController.dataCleanUp();
	}
	
	@RequestMapping(value="orderCleanUp", method=RequestMethod.GET)
	public void orderCleanUp(HttpServletRequest req, HttpServletResponse res) throws IOException {
		String clientIP = adminController.clientIp(req);
		if (logger.isInfoEnabled()) {
			logger.info("dataCleanUp called from - " + clientIP);
		}
		if (0 != clientIP.compareTo("127.0.0.1")) {
			res.sendError(HttpServletResponse.SC_FORBIDDEN, "cannot be called form " + clientIP);
			return;
		}
		
		maintenanceController.orderCleanUp();
	}
	
	@RequestMapping(value="androidVersion", method=RequestMethod.POST, produces="application/json")
	public Map<String, String> androidVersion() {
		Map<String, String> map = new HashMap<String, String>();
		List<AndroidVersion> versions = mongoTemplate.findAll(AndroidVersion.class);
		AndroidVersion version = versions.get(0);
		map.put("androidVersion", version.getAndroidVersion());
		return map;
	}
	
	@InitBinder
	protected void initBinder(WebDataBinder binder) {
		binder.setValidator(new RequestValidator());
	}
	
	@Autowired
	private IdentityController identityController;
	
	@Autowired
	private ProductController productController;
	
	@Autowired
	private OrderController orderController;
	
	@Autowired
	private CartController cartController;
	
	@Autowired
	private DeviceController deviceController;
	
	@Autowired
	private MessageController messageController;
	
	@Autowired
	private AdminController adminController;
	
	@Autowired
	private MaintenanceController maintenanceController;
	
	@Autowired
	private MongoTemplate mongoTemplate; // used by android version interface
	
	private static final Logger logger = LoggerFactory.getLogger(FacadeController.class);
	
}
